#pragma once

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

#include <vector>


class CSGD_Direct3D;
class CSGD_DirectInput;
class CSGD_TextureManager;
class CSGD_XAudio2;

class IGameState;


class CGame
{
public:
	// SINGLETON
	static CGame*	GetInstance		( void );
	static void		DeleteInstance	( void );

	void Initialize( HWND hWnd, HINSTANCE hInstance, 
					 int nScreenWidth, int nScreenHeight,
					 bool bWindowed );

	bool Main( void );

	void Shutdown( void );



	// Screen attribute accessors
	int		GetScreenWidth	( void ) const	{	return	m_nScreenWidth;		}
	int		GetScreenHeight	( void ) const	{	return	m_nScreenHeight;	}
	bool	IsWindowed		( void ) const	{	return	m_bWindowed;		}
	HWND	GetGamehWnd		( void ) const	{	return	m_hWnd;				}

	// Elapsed time accessor
	float	GetElapsedTime	( void ) const	{	return m_fElapsedTime;		}

	// Stack based State Machine
	void	ChangeState( IGameState* pState );
	void	PopState( void );
	void	PushState( IGameState* pState );
	void	ClearStates( void );
	


private:
	// SINGLETON
	static CGame*	s_Instance;
	CGame( void );			// default constructor
	~CGame( void );			// destructor

	CGame( const CGame& );				/* = delete */	// copy constructor
	CGame& operator= ( const CGame& );	/* = delete */	// assignment operator

	
	

	// SGD Wrappers
	CSGD_Direct3D*			m_pD3D;
	CSGD_DirectInput*		m_pDI;
	CSGD_TextureManager*	m_pTM;
	CSGD_XAudio2*			m_pXA;


	// Screen attributes
	int						m_nScreenWidth;
	int						m_nScreenHeight;
	bool					m_bWindowed;

	// Handle to the window
	HWND					m_hWnd;
	// Game state:
	std::vector< IGameState* > m_GameStates;
	


	// Current time
	DWORD					m_dwCurrTime;

	// Time since last frame
	float					m_fElapsedTime;

	// Helper functions
	bool Input ( void );
	void Update( void );
	void Render( void );
};

